using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Linq;
using SZipHandler.Entities;

namespace SZipHandler
{
    public class Worker
    {
        private ConfigReader _configReader;
        private Logger _logger;
        private uTorrentConnector _uTorrentConnector;
        private FileHelper _fileHelper;
        private SzRun _szRun;

        public Worker()
        {
            _configReader = new ConfigReader();
            _logger = new Logger(_configReader.LogPath, _configReader.LoggingStatus);
            _uTorrentConnector = new uTorrentConnector(_configReader.Server, _configReader.Port, _configReader.User, _configReader.Password, _configReader.DownloadFolderPropKey);
            _fileHelper = new FileHelper();
            _szRun = new SzRun(_configReader.ExePath);
            End = false;

            _logger.Log(LogStatus.INFO, string.Format("Init Worker!"));
        }


        public bool End { get; set; }

        public void Work()
        {
            _logger.Log(LogStatus.INFO, string.Format("Start Work!"));

            var doneList = new List<DoneJobs>();

            while (!End)
            {
                try
                {
                    if (File.Exists(_configReader.MemoryFilePath))
                    {
                        _logger.Log(LogStatus.DEBUG, string.Format("Load Memory-File: {0}", _configReader.MemoryFilePath));
                        doneList = JobHandler.LoadFromXML<List<DoneJobs>>(_configReader.MemoryFilePath);
                    }

                    var hashList = new List<string>();

                    _logger.Log(LogStatus.DEBUG, "Get Torrents");
                    foreach (var filesHelper in _uTorrentConnector.GetTorrentFiles())
                    {
                        hashList.Add(filesHelper.Hash);

                        if (doneList.Count(x => x.Hash == filesHelper.Hash) <= 0)
                        {
                            var files = _fileHelper.GetFilesFromArray(filesHelper.Files, _configReader.Format);
                            var relevantFiles = _fileHelper.GetFiles(filesHelper.Folder, files);

                            foreach (var relevantFile in relevantFiles)
                            {
                                _logger.Log(LogStatus.INFO, string.Format("Start File '{0}'", relevantFile));
                                var outFolder = _fileHelper.GetSubFolderForExtract(relevantFile);

                                if (string.IsNullOrEmpty(outFolder))
                                {
                                    _logger.Log(LogStatus.WARNING, string.Format("OutFolder is null"));
                                    continue;
                                }

                                _logger.Log(LogStatus.INFO, string.Format("File extract '{0}' to '{1}'", relevantFile, outFolder));
                                var result = _szRun.RunProcess(relevantFile, outFolder);
                                _logger.Log(LogStatus.INFO, string.Format("Extract Status: {0}", result));

                            }

                            _logger.Log(LogStatus.DEBUG, string.Format("Add Job to DoneList '{0}' | '{1}'", filesHelper.Name, filesHelper.Hash));
                            doneList.Add(new DoneJobs { Hash = filesHelper.Hash, Name = filesHelper.Name, RunTime = DateTime.Now });
                            continue;
                        }
                    }

                    _logger.Log(LogStatus.DEBUG, string.Format("Clear Memory-List"));
                    var indexList = new List<int>();
                    foreach (var job in doneList)
                    {
                        if (hashList.Count(x => x == job.Hash) <= 0)
                            indexList.Add(doneList.IndexOf(job));
                    }
                    foreach (var index in indexList)
                    {
                        doneList.RemoveAt(index);
                    }

                    _logger.Log(LogStatus.DEBUG, string.Format("Save Memory-File: {0}", _configReader.MemoryFilePath));
                    JobHandler.SaveToXML(doneList, _configReader.MemoryFilePath);
                }
                catch (Exception ex)
                {
                    try
                    {
                        _logger.Log(ex);
                    }
                    catch { }
                }

                _logger.Log(LogStatus.DEBUG, string.Format("Thread Sleep {0} Sec", _configReader.SleepInSec));
                Thread.Sleep(TimeSpan.FromSeconds(_configReader.SleepInSec));
            }

            _logger.Log(LogStatus.INFO, string.Format("End Work!"));
        }
    }
}